#pragma once
#include "common.h"
#include <atomic>
#include <thread>
/*
* 作为thread_cache和page_cache的中间层
* 管理从page cache 获取的内存块
* 为多个thread cache提供内存分配能力
* 实现内存的跨线程复用
*/
namespace memory_pool {

struct SpanTracker {
    std::atomic<void*> span_addr{nullptr}; // span的起始地址
    std::atomic<size_t> num_pages{0}; // span的页数
    std::atomic<size_t> block_count{0}; // span的块数
    std::atomic<size_t> free_count{0}; // span中空闲的块数
};

class central_cache {
public:
    // 单例模式
    static central_cache& get_instance() {
        static central_cache instance;
        return instance;
    }
    // thread cache从中央块获取内存块
    void* fetch_range(size_t index);
    // thread cache return 内存块给central cache
    void return_range(void* start, size_t size, size_t index);

private:
    central_cache();
    // 获取页缓存
    void* fetch_from_page_cache(size_t size);
    // 获取页缓存
    SpanTracker* getSpanTracker(void* block_addr);
    void update_span_free_count(SpanTracker* SpanTracker,size_t new_block_count, size_t index);
private:
    // 存储各个大小类的空闲链表头指针
    std::array<std::atomic<void*>,FREE_LIST_SIZE> central_free_list_;
    // 中央缓存自由链表的自旋锁
    std::array<std::atomic_flag, FREE_LIST_SIZE> central_free_list_lock_;
    // 使用数组 存储span的值
    std::array<SpanTracker, 1024> span_tracker_array_;
    // 当前span的总数
    std::atomic<size_t> span_tracker_count{0};

    // 延迟归还
    static constexpr size_t DELAY_FREE_LIST_SIZE = 40;
    std::array<std::atomic<size_t>, FREE_LIST_SIZE> delay_free_list_; //每个大小类的延迟计数
    std::array<std::chrono::steady_clock::time_point, FREE_LIST_SIZE> last_free_time_array_;// 每个大小类的最后归还时间
    static const std::chrono::milliseconds DELAY_INTERVAL;  // 延迟间隔

    bool should_perform_delay_free(size_t index, std::chrono::milliseconds current_time, size_t current_block);
    void perform_delay_free(size_t index);
};
} // namespace memory_pool
